/**
 * 粒子类 - 单个粒子的属性和行为
 */
class Particle {
    constructor(x, y, options = {}) {
        this.position = new Vector2D(x, y);
        this.velocity = options.velocity || Vector2D.random(Math.random() * 3 + 1);
        this.acceleration = options.acceleration || new Vector2D(0, 0);
        
        // 视觉属性
        this.size = options.size || Math.random() * 4 + 2;
        this.color = options.color || `hsl(${Math.random() * 60 + 15}, 100%, 50%)`;
        this.alpha = options.alpha || 1;
        this.life = options.life || Math.random() * 60 + 30;
        this.maxLife = this.life;
        
        // 物理属性
        this.friction = options.friction || 0.98;
        this.gravity = options.gravity || 0.1;
        this.shrink = options.shrink || 0.02;
        
        // 渲染属性
        this.trail = options.trail || false;
        this.glow = options.glow || true;
    }

    update() {
        // 更新物理
        this.velocity.add(this.acceleration);
        this.velocity.multiply(this.friction);
        this.velocity.y += this.gravity;
        this.position.add(this.velocity);
        
        // 更新生命周期
        this.life--;
        this.alpha = this.life / this.maxLife;
        this.size -= this.shrink;
        
        // 重置加速度
        this.acceleration.set(0, 0);
    }

    render(ctx) {
        if (this.life <= 0 || this.size <= 0) return;
        
        ctx.save();
        ctx.globalAlpha = this.alpha;
        
        if (this.glow) {
            // 发光效果
            ctx.shadowColor = this.color;
            ctx.shadowBlur = this.size * 2;
        }
        
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.arc(this.position.x, this.position.y, this.size, 0, Math.PI * 2);
        ctx.fill();
        
        ctx.restore();
    }

    isDead() {
        return this.life <= 0 || this.size <= 0;
    }
}

/**
 * 优化的粒子系统
 * 减少计算量，提高性能
 */

class ParticleSystem {
    constructor() {
        this.particles = [];
        this.maxParticles = 100; // 降低最大粒子数
        this.updateCounter = 0;
        
        // 预定义常用的粒子配置
        this.presets = {
            explosion: {
                count: 8,
                velocity: () => Vector2D.random().multiply(50 + Math.random() * 100),
                size: () => 2 + Math.random() * 3,
                color: () => Math.random() > 0.5 ? '#ff4400' : '#ffaa00',
                life: () => 0.5 + Math.random() * 0.5,
                gravity: 80,
                friction: 0.95
            },
            spark: {
                count: 4,
                velocity: () => Vector2D.random().multiply(30 + Math.random() * 50),
                size: () => 1 + Math.random() * 2,
                color: () => '#ffff88',
                life: () => 0.3 + Math.random() * 0.3,
                gravity: 50,
                friction: 0.9
            },
            muzzleFlash: {
                count: 3,
                velocity: () => Vector2D.random().multiply(20),
                size: () => 1.5 + Math.random() * 1.5,
                color: () => '#ffff00',
                life: () => 0.2 + Math.random() * 0.2,
                gravity: 0,
                friction: 0.85
            },
            wallBreak: {
                count: 6,
                velocity: () => Vector2D.random().multiply(40 + Math.random() * 60),
                size: () => 1.5 + Math.random() * 2.5,
                color: () => Math.random() > 0.6 ? '#8B4513' : '#A0522D',
                life: () => 0.4 + Math.random() * 0.4,
                gravity: 100,
                friction: 0.9
            },
            tankDestroy: {
                count: 12,
                velocity: () => Vector2D.random().multiply(80 + Math.random() * 120),
                size: () => 3 + Math.random() * 4,
                color: () => {
                    const colors = ['#ff0000', '#ff4400', '#ff8800', '#000000'];
                    return colors[Math.floor(Math.random() * colors.length)];
                },
                life: () => 0.8 + Math.random() * 0.8,
                gravity: 120,
                friction: 0.92
            },
            missileExplosion: {
                count: 20,
                velocity: () => Vector2D.random().multiply(120 + Math.random() * 180),
                size: () => 4 + Math.random() * 6,
                color: () => {
                    const colors = ['#ff0000', '#ff3300', '#ff6600', '#ff9900', '#ffcc00', '#000000'];
                    return colors[Math.floor(Math.random() * colors.length)];
                },
                life: () => 1.2 + Math.random() * 1.2,
                gravity: 150,
                friction: 0.9
            }
        };
    }

    createExplosion(x, y, type = 'explosion', intensity = 1.0) {
        if (this.particles.length >= this.maxParticles) {
            this.cleanupOldParticles();
        }
        
        const preset = this.presets[type] || this.presets.explosion;
        const particleCount = Math.min(Math.floor(preset.count * intensity), 20);
        
        for (let i = 0; i < particleCount; i++) {
            if (this.particles.length >= this.maxParticles) break;
            
            this.particles.push({
                x: x + (Math.random() - 0.5) * 4,
                y: y + (Math.random() - 0.5) * 4,
                vx: preset.velocity().x,
                vy: preset.velocity().y,
                size: preset.size() * intensity,
                color: preset.color(),
                life: preset.life() * intensity,
                maxLife: preset.life() * intensity,
                gravity: preset.gravity,
                friction: preset.friction,
                glow: type === 'muzzleFlash' || type === 'spark'
            });
        }
    }

    createDirectionalBurst(x, y, angle, type = 'muzzleFlash') {
        if (this.particles.length >= this.maxParticles) {
            this.cleanupOldParticles();
        }
        
        const preset = this.presets[type] || this.presets.muzzleFlash;
        const particleCount = Math.min(preset.count, 5);
        
        for (let i = 0; i < particleCount; i++) {
            if (this.particles.length >= this.maxParticles) break;
            
            const spread = Math.PI / 6; // 30度扩散
            const particleAngle = angle + (Math.random() - 0.5) * spread;
            const speed = 40 + Math.random() * 30;
            
            this.particles.push({
                x: x + Math.cos(angle) * 15,
                y: y + Math.sin(angle) * 15,
                vx: Math.cos(particleAngle) * speed,
                vy: Math.sin(particleAngle) * speed,
                size: preset.size(),
                color: preset.color(),
                life: preset.life(),
                maxLife: preset.life(),
                gravity: preset.gravity,
                friction: preset.friction,
                glow: true
            });
        }
    }

    addParticle(x, y, config = {}) {
        if (this.particles.length >= this.maxParticles) {
            this.cleanupOldParticles();
            if (this.particles.length >= this.maxParticles) return;
        }

        const particle = {
            x: x,
            y: y,
            vx: (config.velocity && config.velocity.x) || 0,
            vy: (config.velocity && config.velocity.y) || 0,
            size: config.size || 2,
            color: config.color || '#ffffff',
            life: config.life || 1,
            maxLife: config.life || 1,
            gravity: config.gravity || 50,
            friction: config.friction || 0.95,
            glow: config.glow || false
        };

        this.particles.push(particle);
    }

    update() {
        // 每帧更新，避免闪烁
        this.updateParticles();
        
        // 定期清理死亡粒子
        this.updateCounter++;
        if (this.updateCounter % 60 === 0) { // 每60帧清理一次
            this.cleanupDeadParticles();
        }
    }

    updateParticles() {
        const deltaTime = 1/60; // 固定时间步长
        
        for (let i = this.particles.length - 1; i >= 0; i--) {
            const particle = this.particles[i];
            
            // 更新位置
            particle.x += particle.vx * deltaTime;
            particle.y += particle.vy * deltaTime;
            
            // 应用重力
            particle.vy += particle.gravity * deltaTime;
            
            // 应用摩擦力
            particle.vx *= particle.friction;
            particle.vy *= particle.friction;
            
            // 更新生命值
            particle.life -= deltaTime;
            
            // 移除死亡的粒子
            if (particle.life <= 0) {
                this.particles.splice(i, 1);
            }
        }
    }

    cleanupOldParticles() {
        // 移除生命值最低的粒子
        this.particles.sort((a, b) => a.life - b.life);
        const removeCount = Math.min(10, this.particles.length);
        this.particles.splice(0, removeCount);
    }

    cleanupDeadParticles() {
        this.particles = this.particles.filter(particle => particle.life > 0);
    }

    render(ctx) {
        if (this.particles.length === 0) return;
        
        ctx.save();
        
        // 简化渲染，避免复杂的批量处理导致闪烁
        for (const particle of this.particles) {
            const alpha = Math.max(0, particle.life / particle.maxLife);
            if (alpha <= 0) continue;
            
            ctx.globalAlpha = alpha;
            ctx.fillStyle = particle.color;
            
            // 如果有发光效果
            if (particle.glow) {
                ctx.shadowColor = particle.color;
                ctx.shadowBlur = Math.min(3, particle.size);
            } else {
                ctx.shadowBlur = 0;
            }
            
            // 绘制粒子
            ctx.beginPath();
            ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            ctx.fill();
        }
        
        ctx.shadowBlur = 0;
        ctx.globalAlpha = 1;
        ctx.restore();
    }

    limitParticleCount(maxCount) {
        this.maxParticles = maxCount;
        if (this.particles.length > maxCount) {
            // 保留最新的粒子
            this.particles = this.particles.slice(-maxCount);
        }
    }

    getParticleCount() {
        return this.particles.length;
    }

    clear() {
        this.particles = [];
    }
}

window.ParticleSystem = ParticleSystem; 